package gov.pbc.nn.kjgl.maintenance.view;

import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.kjgl.maintenance.entity.SysOperationStaff;
import gov.pbc.nn.kjgl.maintenance.entity.SysPwd;
import gov.pbc.nn.kjgl.maintenance.entity.SysPwdHistory;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.codec.binary.Base64;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.ParseResult;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.view.View;

/**
 * 密码管理
 * 
 * @author Administrator
 * 
 */
@Component
public class SysPwdManagerPR {

	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;
	@Resource(name = CommonJdbcDao.BEAN_ID)
	private CommonJdbcDao jdbcDao;

	public void onInit(View view) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(SysOperationStaff.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("username", ContextHolder.getLoginUserName()));

	}

	/**
	 * 查询当前登录人负责的系统的密码相信
	 * 
	 * @param page
	 * @param criteria
	 */
	@DataProvider
	public void loadPwds(Page<SysPwd> page, Criteria criteria) {
		String sql = "select p.*,s.ab_ from t_sys_pwd p inner join t_sys_operation_staff s on p.SYS_ID_=s.SYS_ID_ where p.INVALID_=0 and s.INVALID_=0  and s.USERNAME_=:username ";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("username", ContextHolder.getLoginUserName());
		ParseResult result = this.jdbcDao.parseCriteria(criteria, true, "p");
		if (result != null) {
			sql += result.getAssemblySql().toString();
			params.putAll(result.getValueMap());
		}
		this.jdbcDao.pagingQuery(page, sql, new RowMapper<SysPwd>() {

			@Override
			public SysPwd mapRow(ResultSet rs, int rowNum) throws SQLException {
				SysPwd pwd = new SysPwd();
				pwd.setId(rs.getString("ID_"));
				pwd.setCreateDate(rs.getDate("CREATE_DATE_"));
				pwd.setCreateUser(rs.getString("CREATE_USER_"));
				pwd.setCycle(rs.getInt("CLCLE_"));
				pwd.setInvalid(rs.getBoolean("INVALID_"));
				pwd.setMd5Text(rs.getString("MD5_TEXT_"));
				pwd.setModifyDate(rs.getDate("MODIFY_DATE_"));
				pwd.setPwdText(rs.getString("PWD_TEXT_"));
				pwd.setServer(rs.getString("SERVER_"));
				pwd.setSysId(rs.getString("SYS_ID_"));
				pwd.setSysName(rs.getString("SYS_NAME_"));
				pwd.setType(rs.getInt("TYPE_"));
				pwd.setUpdateDate(rs.getDate("UPDATE_DATE_"));
				pwd.setUpdateUser(rs.getString("UPDATE_USER_"));
				pwd.setUser(rs.getString("USER_"));
				
				pwd.setBackPwdText(rs.getString("BACK_PWD_TEXT_"));
				pwd.setBackServer(rs.getString("BACK_SERVER_"));
				try {
					pwd = EntityUtils.toEntity(pwd);
					EntityUtils.setValue(pwd, "ab", rs.getString("AB_"));
				} catch (Exception e) {
					e.printStackTrace();
				}

				return pwd;
			}
		}, params);

	}

	@DataResolver
	@Transactional
	public void savePwd(SysPwd pwd) {
		EntityState state = EntityUtils.getState(pwd);
		if (state == EntityState.NEW) {
			this.md5Pwd(pwd, true);
			this.hibernateDao.save(pwd);
		} else {
			if (state == EntityState.MODIFIED) {
				this.md5Pwd(pwd, true);
				this.saveHistoryPwd(pwd.getId());
				this.hibernateDao.update(pwd);
			}
		}
	}

	private void md5Pwd(SysPwd pwd, boolean crypt) {
		String md5Text = Base64.encodeBase64String(pwd.getPwdText().getBytes());
		pwd.setMd5Text(md5Text);
	}

	private void saveHistoryPwd(String id) {
		SysPwd pwd = (SysPwd) this.hibernateDao.get(id, SysPwd.class);
		String str = JSON.toJSONString(pwd,
				SerializerFeature.WriteDateUseDateFormat);
		SysPwdHistory th = JSON.parseObject(str, SysPwdHistory.class);
		th.setOriginalId(id);
		this.hibernateDao.save(th);
	}

	@Expose
	@Transactional
	public void deletePwd(String id) {
		this.hibernateDao.delete(id, SysPwd.class);
	}

	@Expose
	public String getUserAB(String sysId) {
		String sql = "select s.AB_ from t_sys_operation_staff s where s.SYS_ID_=? and s.USERNAME_=?";
		List<String> list = this.jdbcDao.getJdbcTemplate().queryForList(sql,
				String.class, sysId, ContextHolder.getLoginUserName());
		return list.isEmpty() ? null : list.get(0);
	}
}
